package com.example.demo.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * 自定义redis模板
 */
@Configuration
public class RedisTemplateConfiguration {

    /**
     *
     * @param redisConnectionFactory
     * @return
     */
    @Bean
    public RedisTemplate<Object,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
        RedisTemplate<Object,Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        //使用Jackson2JsonRedisSerialize 替换默认序列化
        /**
         *
         定义redis序列化⽅式，提供了多种可选择策略
         JdkSerializationRedisSerializer
            POJO对象的存取场景，使⽤JDK本身序列化机制
            默认机制:ObjectInputStream/ObjectOutputStream进序列化操作
         StringRedisSerializer
            Key或者value为字符串
         Jackson2JsonRedisSerializer
            利用jackson-json⼯具，将pojo实例序列化成json格式存储
         GenericFastJsonRedisSerializer
            另一种javabean与json之间的转换，同时也需要指定Class类型
         */
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        //用于Java对象和JSON字符串之间进行相互转换
        ObjectMapper objectMapper = new ObjectMapper();
        //PrepertyAccessor.ALL 指定ObjectMapper序列化时包含所有类型的属性，公共字段、私有字段、受保护字段等
        //JsonAutoDetect.Visibility.ANY  指定反序列化时包含的属性  必须时非final修饰的类型（待测试）
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        //将设置好的objectMapper置入到序列化对象中
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
        //设置key和value的序列化规则
        //key采用StringRedisSerializer 机制，key一般为字符串
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        //value采用自定义的json序列化机制
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        //设置HashKey 采用StringRedisSerializer
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        //设置HashValue 采用自定义json序列化机制
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        //设置事务
//        redisTemplate.setEnableTransactionSupport(true);
        //初始化完成序列化 所有属性赋值后执行序列化，按照以上的自定义机制 可通过debug试试看，断点到这里
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}
